package com.qqtech.qquan.im.jersey;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.glassfish.jersey.client.JerseyWebTarget;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.qqtech.qquan.im.enums.HTTPMethod;
import com.qqtech.qquan.im.helper.ImSettings;

/**
 * CredentialImpl 凭据
 * 
 * @author woon 2016-07-11
 *
 */
@Service("credential")
public class CredentialImpl implements Credential {
	private Token token;


	@Resource
    private ImSettings imSettings;


	private JerseyWebTarget getTokenRequestTarget() {
		String app_key = imSettings.getAppKey();
		JerseyWebTarget token_target = EndPoints.TOKEN_APP_TARGET
				.resolveTemplate("org_name", app_key.split("#")[0])
				.resolveTemplate("app_name", app_key.split("#")[1]);		
		return token_target;
	}

	@Override
	public Token getToken() {
		if (null == token || token.isExpired()) {
			token = getNewToken();
		}else{
			//LOGGER.info("====IM--OLD accessToken:"+ token.toString()+"createAt:"+ token.getCreateAtCn()+"expiredAt:"+ token.getExpiredAtCn());
		}
		return token;
	}
	//从新从IM获取一个token
	@Override
	public Token getNewToken() {
		String  grant_type = "client_credentials";
		String client_id = imSettings.getClientId();
		String client_secret = imSettings.getClientSecret();
		try {
			JsonNodeFactory factory = new JsonNodeFactory(false);
			ObjectNode objectNode = factory.objectNode();
			objectNode.put("grant_type", grant_type);
			objectNode.put("client_id", client_id);
			objectNode.put("client_secret", client_secret);
			//LOGGER.info("fetching a token by grant_type[" + grant_type + "] client_id[" + client_id + "] and client_secret[" + client_secret + "] .");
			List<NameValuePair> headers = new ArrayList<NameValuePair>();
			headers.add(new BasicNameValuePair("Content-Type", "application/json"));

			ObjectNode tokenRequest = JerseyUtils.sendRequest(getTokenRequestTarget(), objectNode, null,
					HTTPMethod.METHOD_POST, headers);

			if (null != tokenRequest.get("error")) {
                throw new RuntimeException("Some errors occurred while fetching a token by " +
                        "grant_type[" + grant_type + "] client_id[" + client_id + "]" +
                        " and client_secret[" + client_secret + "] .");
			}

			String accessToken = tokenRequest.get("access_token").asText();
			Long expiredAt = System.currentTimeMillis() + tokenRequest.get("expires_in").asLong() * 1000;
			Long cratedAt =System.currentTimeMillis();
			token = new Token(accessToken, cratedAt, expiredAt);
			//LOGGER.info("====IM--NEW accessToken:"+ token.toString()+" createAt:"+ token.getCreateAtCn()+" expiredAt:"+ token.getExpiredAtCn());
		} catch (Exception e) {
            throw new RuntimeException("Some errors occurred while fetching a token by " +
                    "grant_type[" + grant_type + "] client_id[" + client_id + "]" +
                    " and client_secret[" + client_secret + "] .");
        }
		return token;
	}
}
